package home.file;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;

public class FolderPrinter {

	private static final int maxLevel = 5;
	private static final String newLine = System.getProperty("line.separator");
	private static final String levelSpacing = "  ";

	public static void main(String[] args) {
		boolean printFiles = true;

		try {
			File file = new File("/home/gmarcone");

			new FolderPrinter().printFolderTree(System.out, file, printFiles);

		} catch (Exception e) {
			e.printStackTrace(System.out);
		}
	}

	private void printFolderTree(Appendable a, File file, boolean printFiles) throws IOException {
		a.append(file.getAbsolutePath()).append(newLine);
		printFolderTree(a, file, 0, printFiles);
	}

	private void printFolderTree(Appendable a, File file, int level, boolean printFiles) throws IOException {
		if (level > maxLevel) {
			return;
		}

		if (!file.exists() || !file.canRead()) {
			System.out.println("Can not read file " + file.getAbsolutePath());
			return;
		}

		if (file.isDirectory()) {
			for (int i = 0; i < level; i++) {
				a.append(levelSpacing);
			}
			a.append(file.getName()).append(File.separator).append(newLine);

			File[] children = file.listFiles();

			Arrays.sort(children,CUSTOM_FILE_COMPARATOR);

			for (int i = 0; i < children.length; i++) {
				printFolderTree(a, children[i], level + 1, printFiles);
			}

		} else if (printFiles && file.isFile()) {
			for (int i = 0; i < level; i++) {
				a.append(levelSpacing);
			}
			a.append(file.getName()).append(newLine);
		}
	}


	private static final Comparator<File> CUSTOM_FILE_COMPARATOR = new Comparator<File>() {
		private int filesFirst = 1;
		@Override
		public int compare(File o1, File o2) {
			if (o1.isDirectory() && o2.isFile()) {
				return filesFirst;
			} else if (o2.isDirectory() && o1.isFile()) {
				return -filesFirst;
			} else {
				return o1.getName().compareToIgnoreCase(o2.getName());
			}
		}
	};
}
